#include "pch.h"
#include "Domain.h"
#include "States.h"

 #pragma comment(lib, "winmm.lib")
 #pragma comment(lib, "Version.lib")
 #pragma comment(lib, "Bcrypt.lib")
 #pragma comment(lib, "Ws2_32.lib")


int main()
{

    mono::Domain::Desc desc;
    desc.m_DebugName = "Hello world";
    std::shared_ptr<mono::Domain> domain = std::make_shared<mono::Domain>(desc);

    auto assembly = domain->OpenAssembly("../hello.dll");
    auto image = assembly->CreateImage();

    auto clazz = image->GetClazz("", "Helloworld");

    mono::States::Register("Vec3", image->GetClazz("", "Vec3"));

    auto method = clazz->GetMethod("Add", 2);
    auto method2 = clazz->GetMethod("Multiply", 2);
    auto method3 = clazz->GetMethod("Sub", 2);
    auto method4 = clazz->GetMethod("SubData", 3);
    auto method5 = clazz->GetMethod("CC", 3);
    auto method6 = clazz->GetMethod("add_float", 2);
    auto method7 = clazz->GetMethod("SetPos", 1);

    auto obj = domain->NewInstance(*clazz);

    {

        int a = 11;
        int b = 44;

        int res = obj->InvokeMethodArgs<int>(*method2, a, b);
        std::cout << "res is " << res << std::endl;
    }

    {
        std::string s1 = "hello ";
        std::string s2 = "world";
        std::string res2 = obj->InvokeMethodArgs<std::string>(*method3, s1, s2);
        std::cout << res2 << std::endl;
    }
    {
        std::string s1 = "hello ";
        std::string s2 = "my name is";
        std::string s3 = "fbz";
        std::string res = obj->InvokeMethodArgs<std::string>(*method4, s1, s2, s3);
        std::cout << res << std::endl;
    };

    {
        int a1 = 22;
        int b = 2;
        int c = 2;
        int res = obj->InvokeMethodArgs<int>(*method5, a1, b, c);
        std::cout << res << std::endl;
    };

    {
        float a = 11.2f;
        float b = 22.3f;
        float res = obj->InvokeMethodArgs<float>(*method6, a, b);
        std::cout << res << std::endl;
    }

    {
        glm::vec3 pos(1.0f, 2.0f, 5.0f);
        // auto clazzVec3 = clazz->GetInnerClass("Vec3");
        // if(clazzVec3->m_Class)
        // {
        // auto obj2 = domain->NewInstance(*clazzVec3);
        // }

        glm::vec3 res = obj->InvokeMethodArgs<glm::vec3>(*method7, pos);
        std::cout << res.x << " " << res.y << " " << res.z << " " << std::endl;
    }

    return 0;
};
